﻿using HimVoiceStudioCore;
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HimVoiceStudio
{
    public partial class FrmGacha : Form
    {
        private YieldComposeException param;
        public int chosenSeed = -1;
        public FrmGacha(YieldComposeException param)
        {
            this.param = param;
            InitializeComponent();
            Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
            lblGacha.Text = $"[emo {param.param.emotion}]\r\n{param.text}";
        }

        private void FrmGacha_Load(object sender, EventArgs e)
        {

        }

        bool hasResult = false;

        private void btnCompose_Click(object sender, EventArgs e)
        {
            if (composingThread.IsBusy)
            {
                composingThread.CancelAsync();
                btnCompose.Enabled = false;
            }
            else
            {

                if (hasResult && MessageBox.Show(this, "是否清除当前结果并重新合成", "", MessageBoxButtons.YesNo) != DialogResult.Yes) { return; }
                
                clearResult();
                btnCompose.Text = "取消";
                composingThread.RunWorkerAsync();
                numProgress.Value = 0;
                
            }
        }

        private void composingThread_DoWork(object sender, DoWorkEventArgs e)
        {
            System.Threading.Thread.Sleep(100);
            if (composingThread.CancellationPending)
            {
                return;
            }
            for (int i = 0; i < 10; i++)
            {
                try
                {
                    if (composingThread.CancellationPending)
                    {
                        return;
                    }
                    int seed = rnd.Next(1, 2147483645);
                    var comparam = param.param.Clone();
                    comparam.seed = seed;
                    string audio = ComposingService.ComposeAndGetPath(param.text, comparam);
                    string len = "--:--";
                    using(WaveFileReader wfr = new WaveFileReader(audio))
                    {
                        len = wfr.TotalTime.ToString("mm\\:ss\\.F");
                        if (len.EndsWith("."))
                        {
                            len += "0";
                        }
                    }
                    composingThread.ReportProgress(0,new GachaResult() { seed =seed,audioPath = audio,audiolen = len});
                    if (composingThread.CancellationPending)
                    {
                        return;
                    }
                }
                catch(Exception ex)
                {
                    if (composingThread.CancellationPending)
                    {
                        return;
                    }
                }
            }

        }

        private void composingThread_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            hasResult = true;
            var result = e.UserState as GachaResult;
            numProgress.Value = index;
            addButton(result.seed, result.audioPath,result.audiolen);
        }
        int index = 1;
        private void clearResult()
        {
            hasResult = false;
            tblResult.Controls.Clear();
            index = 1;
        }

        private void addButton(int seed,string str,string len)
        {
            Button button = new Button();
            button.Text = $"合成结果 #{index++} {len}\r\nSeed={seed}";
            button.Tag = new GachaResult() { audioPath = str, seed = seed };
            button.Click += btnGachaResult_Click;
            button.MouseUp += btnGachaResult_MouseUp;
            int desiredWidth = tblResult.ClientSize.Width / 2;
            int desiredHeight = tblResult.ClientSize.Height / 5;
            int margin = 3;
            button.Margin = new Padding(margin, margin, margin, margin);
            button.Width = desiredWidth - margin * 2;
            button.Height = desiredHeight - margin * 2;
            button.BackColor = Color.White;
            tblResult.Controls.Add(button);
        }

        private void btnGachaResult_MouseUp(object sender, MouseEventArgs e)
        {
            if(e.Button == MouseButtons.Right)
            {
                var args = ((Button)sender).Tag as GachaResult;
                chosenSeed = args.seed;
                mnuApply.Show((Button)(sender), e.Location);
            }
        }


        private void btnGachaResult_Click(object sender, EventArgs e)
        {
            var args = ((Button)sender).Tag as GachaResult;
            playAudio(args.audioPath);
        }

        private AudioPlayer player = null;
        
        private void playAudio(string path)
        {
            try
            {
                player?.Dispose();
            }
            catch { }
            player = new AudioPlayer(new WaveFileReader(path));
            player.Play();
        }

        private void composingThread_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnCompose.Text = "再次合成";
            btnCompose.Enabled = true;
            if (hasChosenSeed)
            {
                DialogResult = DialogResult.Yes;
                Close();
            }
        }


        private void FrmGacha_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = composingThread.IsBusy;
            if (!e.Cancel)
            {
                try
                {
                    player?.Dispose();
                }
                catch { }
            }
        }

        Random rnd = new Random();

        class GachaResult
        {
            public int seed;
            public string audioPath;
            public string audiolen;
        }

        bool hasChosenSeed = false;

        private void 应用种子ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            
            if(chosenSeed != -1)
            {
                if(composingThread.IsBusy)
                {
                    hasChosenSeed = true;
                    btnCompose.Enabled = false;
                    composingThread.CancelAsync();
                    return;
                }
                DialogResult = DialogResult.Yes;
                Close();
            }
        }
    }
}
